using Mono.Boost.Graph;
using System.Collections.Generic;
using NUnit.Framework;
using System;

[TestFixture]
public class TestComponents
{
    public void run_generic(uint verticesCount, Pair<uint,uint>[] edges, uint[] goodComponent)
    {
        StaticGraph g = new StaticGraph(verticesCount, edges);
        StaticPropertyMap<uint> component = new StaticPropertyMap<uint>(g.highestVertexId+1);

        ConnectedComponents.strongly_connected_components<StaticGraph,StaticPropertyMap<uint>>(g, component);

        uint maxval1 = 0,maxval2=0;
        foreach(uint v in g.vertices)
        {
            maxval1 = Math.Max(maxval1,component[v]);
            maxval2 = Math.Max(maxval2,goodComponent[v]);
        }

        Assert.AreEqual(maxval2+1, maxval1+1, "Wrong number of strongly connected components");

        uint[] tab = new uint[maxval1+1];

        for(uint i=0;i<=maxval1;i++)
            tab[i] = ~0U;

        foreach(uint v in g.vertices)
        {
            uint c = component[v];
            if(tab[c] == ~0U)
                tab[c] = v;
            else
            {
                Assert.AreEqual(goodComponent[v], goodComponent[tab[c]], "Placed two vertices from diffrent components in the same one");
            }
        }

        for(uint i=0;i<=maxval1;i++)
            tab[i] = ~0U;

        foreach(uint v in g.vertices)
        {
            uint c = goodComponent[v];
            if(tab[c] == ~0U)
                tab[c] = v;
            else
            {
                Assert.AreEqual(component[v], component[tab[c]], "Placed two vertices from the same component in different ones");
            }
        }

    }
    [Test]
    public void test1()
    {
        Pair<uint,uint>[] tab = new Pair<uint,uint>[]
        {
            new Pair<uint,uint>(0,1),
            new Pair<uint,uint>(7,0),
            new Pair<uint,uint>(1,5),
            new Pair<uint,uint>(2,3),
            new Pair<uint,uint>(6,4),
            new Pair<uint,uint>(5,7),
            new Pair<uint,uint>(4,2),
            new Pair<uint,uint>(3,4)
        };
        uint[] good = new uint[]{0,0,1,1,1,0,2,0};
        run_generic(8,tab,good);
    }
}
